<template>
  <div class="list-wrapper">
    <!-- 歌手列表 -->
    <scroll
      class="scroll-wrap"
      ref="scroll"
      :data="data"
      :listen-scroll="true"
      :probeType="3"
      @scroll="handleScroll"
      >
      <ul class="list">
        <li class="list-item" ref="listItem" v-for="list in data" :key="list.title">
          <div class="title">{{list.title}}</div>
          <ul class="item-list">
            <li
              v-for="item in list.singerList"
              :key="item.singer_id"
              @click="handleRouteClick(item)"
              >
              <img
                class="avatar"
                v-lazy="item.singer_pic"
                />
              <div class="name">{{item.singer_name}}</div>
            </li>
          </ul>
        </li>
      </ul>
    </scroll>
    <!-- 字母表 -->
    <div class="alphabet-wrap">
      <ul
        class="alphabet"
        @touchstart="handleTouchStart"
        @touchmove.stop.prevent="handleTouchMove"
        @touchend="handleTouchEnd"
        ref="alphabet"
        >
        <li
          v-for="(item, index) in alphabetList"
          :key="item"
          @click="handleBtnClick"
          :class='{ "active": index === currentIndex }'
          >
          {{item}}
        </li>
      </ul>
    </div>
    <!-- 固定标题 -->
    <div class="list-fixed" v-show="fixedTitleShow" ref="fixedTitle">
      <h1 class="fixed-title">
        {{fixedTitleText}}
      </h1>
    </div>
    <!-- Loading -->
    <div class="loading-wrap" v-show="!data.length">
      <loading />
    </div>
  </div>
</template>

<script>
import Scroll from 'base/scroll/scroll'
import Loading from 'base/loading/loading'
export default {
  name: 'listview',
  components: {
    Scroll,
    Loading
  },
  props: {
    data: {
      type: Array,
      default () {
        return []
      }
    }
  },
  computed: {
    alphabetList () {
      return this.data.map((item) => {
        return item.title.substring(0, 1)
      })
    },
    fixedTitleText () {
      const titleArr = this.data.map((item) => {
        return item.title
      })
      return titleArr[this.currentIndex]
    }
  },
  updated () {
    this.startY = this.$refs.alphabet.offsetTop + 72 + 16
  },
  data () {
    return {
      startMove: false,
      startY: 0,
      timer: null,
      scrollY: -1,
      listHeight: [],
      currentIndex: 0,
      fixedTitleShow: false, // 控制固定标题显示/隐藏
      diff: -1
    }
  },
  methods: {
    handleBtnClick (e) {
      // 获取当前点击的字母表索引
      const index = this.alphabetList.findIndex((item) => {
        return e.target.innerText === item
      })

      // 获取索引对应的 DOM
      const el = this.$refs.listItem[index]
      // 调用 bscroll 的 scrollToElement 方法实现切换
      this.$refs.scroll.scrollToEl(el)
    },
    handleTouchStart () {
      // 获取当前手指到顶部的距离
      this.startMove = true
    },
    handleTouchMove (e) {
      if (this.startMove) {
        if (this.timer) {
          clearTimeout(this.timer)
        }

        this.timer = setTimeout(() => {
          this.currentY = e.touches[0].clientY
          let index = Math.floor((this.currentY - this.startY) / 16)
          if (index >= 0 && index <= 26) {
            console.log(index)
            // 获取索引对应的 DOM
            const el = this.$refs.listItem[index]
            // 调用 bscroll 的 scrollToElement 方法实现切换
            this.$refs.scroll.scrollToEl(el)
          }
        }, 20)
      }
    },
    handleTouchEnd () {
      this.startMove = false
    },
    handleScroll (pos) {
      // console.log(pos)
      this.scrollY = pos.y
    },
    _calculateHeight () {
      const list = this.$refs.listItem // 获取每个组
      let height = 0
      this.listHeight.push(height) // 第一组高度为 0

      // 遍历每个组，并获取其高度，添加到数组 listHeight 中
      list.forEach((item) => {
        height += item.clientHeight
        this.listHeight.push(height)
      })
    },
    handleRouteClick (singer) {
      // console.log(id)
      this.$emit('route', singer)
    },
    refresh () {
      this.$refs.scroll.refresh()
    }
  },
  watch: {
    data () {
      // listview 会接收一个 data(即要渲染的数据)
      // 我们监听 data 的变化，当 data 变化时，计算高度
      setTimeout(() => {
        // 数据变化到 DOM 变化有一个延迟，所以使用定时器节约性能
        this._calculateHeight()
      }, 20)
    },
    scrollY (newY) {
      const listHeight = this.listHeight

      // console.log(listHeight)
      // 如果滚动到顶部，则 newY > 0
      if (newY >= 0) {
        this.fixedTitleShow = false // 固定标题隐藏
      } else {
        this.fixedTitleShow = true // 固定标题显示
      }

      if (newY > 0) {
        this.currentIndex = 0
        return
      }

      listHeight.forEach((height, index) => {
        let height2 = listHeight[index + 1]

        // 在中间部分滚动
        if (-newY >= height && -newY < height2) {
          this.currentIndex = index
          // console.log(this.currentIndex)
          this.diff = height2 + newY
          // console.log(this.diff)
        }
      })
    },
    diff (newVal) {
      // console.log(newVal)
      if (newVal <= 24) {
        this.$refs.fixedTitle.style.top = `${-(24 - newVal)}px`
        return
      }

      this.$refs.fixedTitle.style.top = '0px'
    }
  }
}
</script>

<style lang="stylus" scoped>
  @import '~common/stylus/variable.styl'
  .list-wrapper {
    position: absolute
    top: 0
    bottom: 0
    width: 100%
    overflow: hidden
    .scroll-wrap {
      height: 100%
    }
    .list {
      .list-item {
        color: $color-text-l
        .title {
          padding-left: 16px
          line-height: 24px
          font-size: $font-size-small
          background: $color-highlight-background
          margin-bottom: 20px
        }
        .item-list {
          li {
            display: flex
            padding: 0 24px
            padding-bottom: 20px
            .avatar {
              width: 48px
              height: 48px
              border-radius: 50%
            }
            .name {
              flex: 1
              margin-left: 24px
              font-size: $font-size-medium
              line-height: 48px
            }
          }
        }
      }
    }
    .alphabet-wrap {
      position: absolute
      right: 0
      top: 0
      bottom: 0
      display: flex
      flex-direction: column
      justify-content: center
      font-size: $font-size-small
      color: $color-text-l
      .alphabet {
        background: $color-background-d
        padding: 16px 0
        border-radius: 12px
        li {
          padding: 0 4px
          line-height: 16px
          text-align: center
          &.active {
            color: $color-theme
          }
        }
      }
    }
    .list-fixed {
      position: absolute
      top: 0
      width: 100%
      padding-left: 16px
      line-height: 24px
      font-size: $font-size-small
      color: $color-text-l
      background: $color-highlight-background
    }
    .loading-wrap {
      position: absolute
      top: 0
      bottom: 0
      width: 100%
      display: flex
      flex-direction: column
      justify-content: center
      .loading {
        margin-top: 0
      }
    }
  }
</style>
